package com.freak.kotlinfitnessserver.factory.response

import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothGattCharacteristic
import com.freak.kotlinfitnessserver.constant.fitness.DisProtocolConstant
import com.freak.kotlinfitnessserver.constant.fitness.FitnessProtocolConstant
import com.freak.kotlinfitnessserver.data.FitnessConfigData
import com.freak.kotlinfitnessserver.factory.IResponseFactory
import com.freak.kotlinfitnessserver.util.ByteUtil
import com.freak.kotlinfitnessserver.util.LogUtil

class IndoorBikeResponseFactory : IResponseFactory {
    private val TAG: String = "IndoorBikeResponseFactory"
    override fun handleCharacteristicReadRequest(
        device: BluetoothDevice?,
        requestId: Int,
        offset: Int,
        characteristic: BluetoothGattCharacteristic?,
        fitnessConfigData: FitnessConfigData?
    ): ByteArray {
        val uuid = characteristic?.uuid
        uuid ?: let {
            LogUtil.i(TAG, "uuid is null")
            return ByteArray(0)
        }
        fitnessConfigData ?: let {
            LogUtil.i(TAG, "fitnessConfigData is null")
            return ByteArray(0)
        }
        LogUtil.i(TAG, "handleCharacteristicReadRequest uuid = $uuid")
        when (uuid) {
            DisProtocolConstant.systemID -> {
                // 字节数不能太长，太长会导致出现回调到onCharacteristicReadRequest的时候，
                // 导致offset出现不为0的情况，并且出现多次
                LogUtil.i(
                    TAG,
                    "systemID byteArray = ${
                        ByteUtil.bytesToHexString(
                            fitnessConfigData.systemId.toByteArray(
                                Charsets.UTF_8
                            )
                        )
                    } string = ${fitnessConfigData.systemId}"
                )
                return fitnessConfigData.systemId.toByteArray(Charsets.UTF_8)
            }

            DisProtocolConstant.modelNumber -> {
                LogUtil.i(
                    TAG,
                    "modelNumber byteArray = ${
                        ByteUtil.bytesToHexString(
                            fitnessConfigData.modelNumber.toByteArray(
                                Charsets.UTF_8
                            )
                        )
                    } string = ${fitnessConfigData.modelNumber}"
                )
                return fitnessConfigData.modelNumber.toByteArray(Charsets.UTF_8)
            }

            DisProtocolConstant.serialNumber -> {
                LogUtil.i(
                    TAG,
                    "serialNumber byteArray = ${
                        ByteUtil.bytesToHexString(
                            fitnessConfigData.serialNumber.toByteArray(
                                Charsets.UTF_8
                            )
                        )
                    } string = ${fitnessConfigData.serialNumber}"
                )
                return fitnessConfigData.serialNumber.toByteArray(Charsets.UTF_8)
            }

            DisProtocolConstant.firmwareRevision -> {
                LogUtil.i(
                    TAG,
                    "firmwareRevision byteArray = ${
                        ByteUtil.bytesToHexString(
                            fitnessConfigData.firmwareRevision.toByteArray(
                                Charsets.UTF_8
                            )
                        )
                    } string = ${fitnessConfigData.firmwareRevision}"
                )
                return fitnessConfigData.firmwareRevision.toByteArray(Charsets.UTF_8)
            }

            DisProtocolConstant.hardwareRevision -> {
                LogUtil.i(
                    TAG,
                    "hardwareRevision byteArray = ${
                        ByteUtil.bytesToHexString(
                            fitnessConfigData.hardwareRevision.toByteArray(
                                Charsets.UTF_8
                            )
                        )
                    } string = ${fitnessConfigData.hardwareRevision}"
                )
                return fitnessConfigData.hardwareRevision.toByteArray(Charsets.UTF_8)
            }

            DisProtocolConstant.softwareRevision -> {
                LogUtil.i(
                    TAG,
                    "softwareRevision byteArray = ${
                        ByteUtil.bytesToHexString(
                            fitnessConfigData.softwareRevision.toByteArray(
                                Charsets.UTF_8
                            )
                        )
                    } string = ${fitnessConfigData.softwareRevision}"
                )
                return fitnessConfigData.softwareRevision.toByteArray(Charsets.UTF_8)
            }

            DisProtocolConstant.manufacturerName -> {
                LogUtil.i(
                    TAG,
                    "manufacturerName byteArray = ${
                        ByteUtil.bytesToHexString(
                            fitnessConfigData.manufacturerName.toByteArray(
                                Charsets.UTF_8
                            )
                        )
                    } string = ${fitnessConfigData.manufacturerName}"
                )
                return fitnessConfigData.manufacturerName.toByteArray(Charsets.UTF_8)
            }

            FitnessProtocolConstant.SupportedSpeedRange -> {
                val byteArray = ByteArray(6)
                var position = 0
                ByteUtil.intToTwoByteArray(byteArray, fitnessConfigData.minSpeed, position)
                position += 2
                ByteUtil.intToTwoByteArray(byteArray, fitnessConfigData.maxSpeed, position)
                position += 2
                ByteUtil.intToTwoByteArray(byteArray, fitnessConfigData.minSpeedIncrement, position)
                LogUtil.i(
                    TAG,
                    "SupportedSpeedRange byteArray = ${ByteUtil.bytesToHexString(byteArray)}"
                )
                return byteArray
            }

            FitnessProtocolConstant.SupportedHeartRateRange -> {
                val byteArray = ByteArray(6)
                var position = 0
                ByteUtil.intToTwoByteArray(byteArray, fitnessConfigData.minHeartRate, position)
                position += 2
                ByteUtil.intToTwoByteArray(byteArray, fitnessConfigData.maxHeartRate, position)
                position += 2
                ByteUtil.intToTwoByteArray(
                    byteArray,
                    fitnessConfigData.minHeartRateIncrement,
                    position
                )
                LogUtil.i(
                    TAG,
                    "SupportedHeartRateRange byteArray = ${ByteUtil.bytesToHexString(byteArray)}"
                )
                return byteArray
            }

            FitnessProtocolConstant.SupportedPowerRange -> {
                val byteArray = ByteArray(6)
                var position = 0
                ByteUtil.intToTwoByteArray(byteArray, fitnessConfigData.minPower, position)
                position += 2
                ByteUtil.intToTwoByteArray(byteArray, fitnessConfigData.maxPower, position)
                position += 2
                ByteUtil.intToTwoByteArray(byteArray, fitnessConfigData.minPowerIncrement, position)
                LogUtil.i(
                    TAG,
                    "SupportedPowerRange byteArray = ${ByteUtil.bytesToHexString(byteArray)}"
                )
                return byteArray
            }

            FitnessProtocolConstant.SupportedResistanceLevelRange -> {
                val byteArray = ByteArray(6)
                var position = 0
                ByteUtil.intToTwoByteArray(
                    byteArray,
                    fitnessConfigData.minResistanceLevel,
                    position
                )
                position += 2
                ByteUtil.intToTwoByteArray(
                    byteArray,
                    fitnessConfigData.maxResistanceLevel,
                    position
                )
                position += 2
                ByteUtil.intToTwoByteArray(
                    byteArray,
                    fitnessConfigData.minResistanceLevelIncrement,
                    position
                )
                LogUtil.i(
                    TAG,
                    "SupportedResistanceLevelRange byteArray = ${ByteUtil.bytesToHexString(byteArray)}"
                )
                return byteArray
            }

            FitnessProtocolConstant.TrainingStatus -> {
                val byteArray = ByteArray(2)
                var position = 0
                ByteUtil.intToOneByteArray(byteArray, 1, position)
                position += 1
                ByteUtil.intToOneByteArray(byteArray, 1, position)
                LogUtil.i(
                    TAG,
                    "TrainingStatus byteArray = ${ByteUtil.bytesToHexString(byteArray)}"
                )
                return byteArray
            }

            FitnessProtocolConstant.FitnessMachineFeature -> {
                var byteArray = ByteArray(0)
                byteArray =
                    byteArray.plus(ByteUtil.convertToFourByteLittleEndian(fitnessConfigData.fitnessMachineFeaturesFlag))
                byteArray =
                    byteArray.plus(ByteUtil.convertToFourByteLittleEndian(fitnessConfigData.targetSettingFeaturesFlag))
                LogUtil.i(
                    TAG,
                    "FitnessMachineFeature byteArray = ${ByteUtil.bytesToHexString(byteArray)}"
                )
                return byteArray
            }
        }
        return ByteArray(0)
    }
}